﻿// Shader-Based-Image-Processing (SBIP)
// http://code.google.com/p/sbip/
//
// Copyright © Frank Nagl, 2009-2011
// admin@franknagl.de
//
namespace SBIP.OptionsForms.NonSBIP
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
    using Filter;
    using Filter.NonSBIP;
    using Helper;

    /// <summary>Filter specified properties form.</summary>
    public partial class NSKeyPointAndColorBasedSegmentationForm : Form
    {
        private readonly Processor processor;        
        private readonly NSCannyEdgeDetector canny;
        private readonly NSKeyPointAndColorBasedSegmentation nsfilter;
        private bool useCanny;

        /// <summary>
        /// Initializes a new instance of the 
        /// <see cref="NSKeyPointAndColorBasedSegmentationForm"/> class.
        /// </summary>
        /// <param name="processor">The processor.</param>
        public NSKeyPointAndColorBasedSegmentationForm(Processor processor)
        {
            InitializeComponent();

            this.processor = processor;
            nsfilter = new NSKeyPointAndColorBasedSegmentation();
            nsfilter.Tolerance = Color.FromArgb(20, 20, 20);
            canny = new NSCannyEdgeDetector();
            processor.Filter = new Original();
            useCanny = true;
        }

        #region Canny tab control events
        private void TrbarHighThresholdValueChanged(object sender, EventArgs e)
        {
            canny.HighThreshold = (byte)trbarHighThreshold.Value;
            lbHighThreshold.Text = trbarHighThreshold.Value.ToString();
        }

        private void TrbarLowThresholdValueChanged(object sender, EventArgs e)
        {
            canny.LowThreshold = (byte)trbarLowThreshold.Value;
            lbLowThreshold.Text = trbarLowThreshold.Value.ToString();
        }

        private void TrbarGaussSizeValueChanged(object sender, EventArgs e)
        {
            canny.GaussianSize = trbarGaussSize.Value;
            lbGaussSize.Text = trbarGaussSize.Value.ToString();
        }

        private void TrbarGaussSigmaValueChanged(object sender, EventArgs e)
        {
            canny.GaussianSigma = trbarGaussSigma.Value / 1000.0f;
            lbGaussSigma.Text = (trbarGaussSigma.Value / 1000.0f).ToString();
        }
        #endregion Canny tab control events

        private void RdbtnYesCannyCheckedChanged(object sender, EventArgs e)
        {
            useCanny = rdbtnYesCanny.Checked;
        }

        private void BtnColorChangeClick(object sender, EventArgs e)
        {
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                nsfilter.Tolerance = colorDialog.Color;
                btnColorChange.BackColor = colorDialog.Color;
                lbTolerance.Text = string.Format(
                    "Red: {0}   Green: {1}   Blue: {2}",
                    colorDialog.Color.R,
                    colorDialog.Color.G,
                    colorDialog.Color.B);
            }
        }

        private void BtnProcessClick(object sender, EventArgs e)
        {            
            //EndlessProgressBarFormInThread form = 
            //    new EndlessProgressBarFormInThread(
            //        "Do objects extracting ... ", 
            //        "Please wait, this takes a few seconds.");
            //form.Start();
            try
            {
                Bitmap bitmap = 
                    processor.OriginalBitmap.PixelFormat == PixelFormat.Format32bppArgb ||
                    processor.OriginalBitmap.PixelFormat == PixelFormat.Format32bppRgb
                     ? BitmapConverter.ARGBToRGB(processor.OriginalBitmap)
                     : processor.OriginalBitmap;

                if (useCanny)
                {
                    NSCannyEdgeMarker marker = new NSCannyEdgeMarker();
                    marker.CannyEdgeDetector = canny;
                    bitmap = marker.Apply(bitmap);
                }

                string[] lines = Regex.Split(txtBoxKeyPoints.Text, "\r\n");
                List<PixelRGBA> keypoints = new List<PixelRGBA>(lines.Length);
                foreach (string l in lines)
                {
                    string[] content = Regex.Split(l, ";");
                    int x, y;
                    byte r, g, b;
                    if (content.Length == 5 &&
                        int.TryParse(content[0], out x) &&
                        int.TryParse(content[1], out y) &&
                        byte.TryParse(content[2], out r) &&
                        byte.TryParse(content[3], out g) &&
                        byte.TryParse(content[4], out b))
                    {
                        Color c = processor.OriginalBitmap.GetPixel(x, y);
                        keypoints.Add(new PixelRGBA
                                          {
                                              X = x, 
                                              Y = y, 
                                              R = c.R, 
                                              G = c.G, 
                                              B = c.B, 
                                              Reserved = Color.FromArgb(255, r, g, b)
                                          });
                    }
                    else
                    {
                        MessageBox.Show(@"Key point entries are incorrect.");
                        return;
                    }
                }

                nsfilter.KeyPoints = keypoints;
                bitmap = nsfilter.Apply(bitmap);
                processor.ChangeTexture(bitmap);
            }
            catch (ArgumentException aex)
            {
                MessageBox.Show(aex.Message);
                BtnResetClick(sender, e);
            }

            // lbContourNumbers.Text = canny.Contours.Count.ToString();

            // form.End();
        }

        private void BtnResetClick(object sender, EventArgs e)
        {
            processor.ResetTexture();
        }
    }
}
